package common.database.implementations;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.object.StoredProcedure;

import common.database.interfaces.BaseDAO;
//@Transactional
public abstract class BaseDAOImpl<T> extends NamedParameterJdbcDaoSupport implements
		BaseDAO<T> {

	

	/**
	 * 
	 * �����ڸ�����ݿ�,insert,update, delete
	 * 
	 * 
	 * 
	 * @param namedSql
	 * 
	 *            :�������ģӣѣ���䣬���Ҳ�����������ͣʣ����£����е��������Ӧ
	 * 
	 * @param javaBean
	 * 
	 *            ���������������
	 * 
	 * @return
	 * @throws Exception 
	 * @throws SQLException
	 */

	public int update(String namedSql, Object javaBean)throws Exception {

		SqlParameterSource paramSource = new BeanPropertySqlParameterSource(
				javaBean);
		int result = this.getNamedParameterJdbcTemplate().update(namedSql,
				paramSource);
//		throw new Exception("xxx");
		//this.update(namedSql, javaBean);
		return result;

	}

	public int[] batchUpdate(String namedSql, List<T> javaBeanList)throws Exception {
		SqlParameterSource[] paramSources = new BeanPropertySqlParameterSource[javaBeanList.size()];
		for(int i=0;i<javaBeanList.size();i++){
			Object object = javaBeanList.get(i);
			SqlParameterSource paramSource = new BeanPropertySqlParameterSource(object);
			paramSources[i]=paramSource;
		}
		return this.getNamedParameterJdbcTemplate().batchUpdate(namedSql, paramSources);
	}

	public int commonUpdate(String sql, Object... paramValue)throws Exception {

		return this.getJdbcTemplate().update(sql, paramValue);

	}

	public int commonUpdate(String sql, List<T> paramList)throws Exception {

		return this.getJdbcTemplate().update(sql, paramList.toArray());

	}

	public T getJavaBean(String sql, Class<T> returnType,

	Object... paramValue)throws Exception {

		RowMapper<T> rowMapper = new BeanPropertyRowMapper<T>(returnType);

		return this.getJdbcTemplate()

				.queryForObject(sql, rowMapper, paramValue);
	}

	public List<T> getList(String sql, Class<T> returnType,

	Object... paramValue)throws Exception {

		RowMapper<T> rowMapper = new BeanPropertyRowMapper<T>(returnType);

		return this.getJdbcTemplate().query(sql, rowMapper, paramValue);

	}

	public List<T> getList(String sql, Class<T> returnType)throws Exception {

		RowMapper<T> rowMapper = new BeanPropertyRowMapper<T>(returnType);

		return this.getJdbcTemplate().query(sql, rowMapper);

	}

	/**
	 * 
	 * �����ܼ�¼��
	 * 
	 * 
	 * 
	 * @param countSQL
	 * 
	 *            �����ܼ�¼���count���
	 * 
	 * @param paramValue
	 * 
	 *            ����ж�Ӧ�Ĳ���ֵ
	 * 
	 * @return �ܼ�¼��
	 */

	public int getCount(String countSQL, List paramValue)throws Exception {

		return this.getJdbcTemplate().queryForInt(countSQL,

		paramValue.toArray());

	}

	public int getCount(String countSQL, Object... paramValue)throws Exception {

		return this.getJdbcTemplate().queryForInt(countSQL, paramValue);

	}


	public Map<?, ?> executeStroeProcedure(String procedureName,
			SqlParameter[] procedureParameters, Object... parameterValues)throws Exception {
		CustomStoredProcedure sproc = new CustomStoredProcedure(
				getDataSource(), procedureName, procedureParameters);
		Map<?, ?> out = sproc.execute(parameterValues);
		return out;
	}

	private class CustomStoredProcedure extends StoredProcedure {
		public CustomStoredProcedure(DataSource ds, String proname,
				SqlParameter[] parameters) throws Exception{
			setDataSource(ds);
			setFunction(false);
			setSql(proname);
			this.setParameters(parameters);
			// declareParameter(new SqlParameter("g_gdfgsbm", Types.VARCHAR));
			// declareParameter(new SqlParameter("g_cbyear", Types.NUMERIC));
			// declareParameter(new SqlParameter("g_cbmonth", Types.NUMERIC));
			compile();

		}

		@SuppressWarnings("unchecked")
		public Map execute(Object... p) {
			Map inParams = new HashMap();
			int dpsize = this.getDeclaredParameters().size();
			for (int i = 0; i < dpsize; i++) {
				SqlParameter s = (SqlParameter) this.getDeclaredParameters()
						.get(i);
				inParams.put(s.getName(), p[i]);

			}
			Map out = execute(inParams);
			return out;
		}
	}

	/*
	 * public PageModel getPageModel(PageModel model,
	 * 
	 * StringBuilder querySQL, StringBuilder countSQL,
	 * 
	 * StringBuilder whereSQL, List paramList, Class<T> returnType) {
	 * 
	 * querySQL.append(whereSQL);
	 * 
	 * countSQL.append(whereSQL);
	 * 
	 * // �����ܼ�¼��
	 * 
	 * int allCount = this.getCount(countSQL.toString(), paramList);
	 * 
	 * // ��ȡ��ҳ��¼��
	 * 
	 * // 1����������ķ�ҳ���
	 * 
	 * querySQL.insert(0, PAGE_SQL_PREFIX);
	 * 
	 * querySQL.append(PAGE_SQL_END);
	 * 
	 * 
	 * 
	 * // 2.�ѷ�ҳ����еĲ���ֵ���뵽paramList��
	 * 
	 * paramList.add(model.getNumPerPage()* model.getPageNum());
	 * 
	 * paramList.add(( model.getPageNum() - 1) *model.getNumPerPage());
	 * 
	 * List result = this.getList(querySQL.toString(), returnType,
	 * 
	 * paramList.toArray());
	 * 
	 * PageModel models = new PageModel();
	 * 
	 * models.setTotalCount(allCount);
	 * 
	 * models.setNumPerPage(model.getNumPerPage());
	 * 
	 * models.setPageNum(model.getPageNum());
	 * 
	 * models.setResult(result);
	 * 
	 * models.setOrderDirection(model.getOrderDirection());
	 * 
	 * models.setOrderField(model.getOrderField());
	 * 
	 * return models;
	 * 
	 * }
	 */

}
